﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WellDone
{
    public static class Globals
    {
        // Numeric Constants
        public const double k_dbl_button_spacing = 10.0;
        public const double k_dbl_checkbox_height = 30.0;
        public const double k_dbl_small_checkbox_height = 24.0;
        public const double k_dbl_menu_button_font_size = 28.0;
        public const double k_dbl_menu_small_button_font_size = 20.0;
        public const double k_dbl_nav_button_font_size = 18.0;
        public const double k_dbl_option_group_min_height = 140.0;
        public const double k_dbl_option_group_width = 360;
        public const double k_dbl_option_padding = 3.0;
        public const double k_dbl_radio_button_height = 30.0;
        public const double k_dbl_small_radio_button_height = 20.0;
        public const int k_int_max_options_per_column = 11;
        public const int k_int_max_tables = 99;
        public const int k_int_max_splits = 8;
        public const int k_int_protocol_offset = 8;
        public const int k_int_small_rows = 5;
        public const int k_int_status_open = 0;
        public const int k_int_status_sent = 1;
        public const int k_int_status_ready = 2;
        public const int k_int_status_delivered = 3;
        public const int k_int_status_closing = 4;
        public const int k_int_status_closed = 5;
        public const int k_int_time_interval_once = 0;
        public const int k_int_time_interval_daily = 1;
        public const int k_int_time_interval_weekly = 2;
        public const int k_int_time_interval_monthly = 3;
        public const int k_dbl_menugroup_button_margin = 130;
        public const double k_dbl_nav_button_width = 180;
        public const double k_dbl_menu_button_width = 130;
        public const double k_dbl_menugroup_button_width = 130;
        public const double k_dbl_menugroup_button_height = 110;


        // String constants
        public const string k_str_demo_service_address = "https://secure.welldonepos.co/Demo/WellDone.svc";        
        public const string k_str_memo = "OpenRPOS v1.0";
        public const string k_str_pizza_whole = "Whole Pizza";
        public const string k_str_pizza_first_half = "1st Half";
        public const string k_str_pizza_second_half = "2nd Half";
        public const string k_str_settings_hide_login_links = "Hide Login Links:";
        public const string k_str_settings_service_address = "Service Address";
        public const string k_str_settings_show_close_button = "Show Close Button?";
        public const string k_str_settings_show_print_button = "Show Print Button?";
        public const string k_str_settings_use_timeClock_button = "Use Time Clock?";
        public const string k_str_settings_receipt_print_route = "Receipt Print Route:";
        public const string k_str_settings_order_print_route = "Order Print Route:";
        public const string k_str_value_false = "FALSE";
        public const string k_str_value_no = "NO";
        public const string k_str_value_one = "1";
        public const string k_str_value_true = "TRUE";
        public const string k_str_value_yes = "YES";
        public const string k_str_value_zero = "0";
        public const string k_str_punch_in = "Punch In";
        public const string k_str_punch_out = "Punch Out";
        public const string k_str_no_menu_group = "No Menu Group";

        // Misc. Data
        public static bool initialized = false;
        public static bool pinloginEnable = false;
        public static bool processMercury = false;
        public static bool processUSAePay = false;
        public static bool processBlackline = false;
        public static bool timeclockbtnEnable = false;
        public static bool timeclockEnable = false;
        public static bool chkTimeclockEnable = false;
        public static bool defaultTableView = false;
        public static int loginID;
        public static int tenantID = -1;
        public static int token;
        public static double tax_rate=0.0; // Load from configuration table
        public static double credit_threshold = 0.0;
        public static string strUSAePaySourceKey = "";
        public static string strUSAePayPin = "";
        public static string strBlacklineUrl = "";
        public static string strBlacklineKey = "";
        public static string strBlacklinePassword = "";
        public static string strBlacklineTerminalID = "";
        public static string strExceptionMessage = "";
        public static ServiceReferenceOpenRPOS.ServiceOpenRPOSClient client = new ServiceReferenceOpenRPOS.ServiceOpenRPOSClient();
        public static ServiceReferenceMercury.MercuryClient mercuryClient;
        public static ServiceReferenceUSAePay.ServiceUSAePayClient usaepayClient;
        public static ServiceReferenceMercuryHostedCheckout.HCServiceSoapClient mercuryHostedCheckoutClient;
        public static ServiceReferenceOpenRPOS.Login currentLogin;
        public static Uri InputURI = null;
        public static ObservableCollection<ServiceReferenceOpenRPOS.Blackline> BlacklineRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Blackline>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Configuration> ConfigurationRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Configuration>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Discount> DiscountRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Discount>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Login> LoginRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Login>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuCategory> MenuCategoryRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuCategory>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuCategory> MenuCategoryNoGroupRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuCategory>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuGroup> MenuGroupRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuGroup>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuItem> MenuItemRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuItem>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuItemOptionGroup> MenuItemOptionGroupRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuItemOptionGroup>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuOption> MenuOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuOption>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Mercury> MercuryRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Mercury>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OpenItem> OpenItemRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OpenItem>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OptionGroup> OptionGroupRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OptionGroup>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderCheck> OrderPartialCheckRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderCheck>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderCheck> OrderCheckRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderCheck>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.PartialPayment> PartialPaymentRecords = new ObservableCollection<ServiceReferenceOpenRPOS.PartialPayment>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail> OrderDetailRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderOption> OrderOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderOption>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary> OrderSummaryRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.PaymentType> PaymentTypeRecords = new ObservableCollection<ServiceReferenceOpenRPOS.PaymentType>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.PrintQueue> PrintQueueRecords = new ObservableCollection<ServiceReferenceOpenRPOS.PrintQueue>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Refund> RefundRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Refund>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.SplitItem> SplitItemRecords = new ObservableCollection<ServiceReferenceOpenRPOS.SplitItem>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.TableLayout> TableLayoutRecords = new ObservableCollection<ServiceReferenceOpenRPOS.TableLayout>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.TableSpecification> TableSpecificationRecords = new ObservableCollection<ServiceReferenceOpenRPOS.TableSpecification>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.TimePrice> TimePriceRecords = new ObservableCollection<ServiceReferenceOpenRPOS.TimePrice>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.TimeSheet> TimeSheetRecords = new ObservableCollection<ServiceReferenceOpenRPOS.TimeSheet>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.Role> RoleRecords = new ObservableCollection<ServiceReferenceOpenRPOS.Role>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.EmployeeRole> EmployeeRoleRecords = new ObservableCollection<ServiceReferenceOpenRPOS.EmployeeRole>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.USAePay> USAePayRecords = new ObservableCollection<ServiceReferenceOpenRPOS.USAePay>();
               
        public static async Task<Boolean> OpenDrawer()
        {
            // Open the cash drawer
            ServiceReferenceOpenRPOS.PrintQueue pq = new ServiceReferenceOpenRPOS.PrintQueue();
            pq.bFilterPrintOrder = true;
            pq.col_PrintOrder = false;
            pq.bFilterPrintReceipt = true;
            pq.col_PrintReceipt = false;
            pq.bFilterOrderCheckID = false;
            pq.bFilterOrderSummaryID = false;
            pq.bFilterOpenCashDrawer = true;
            pq.col_OpenCashDrawer = true;
            pq.bFilterPrinted = true;
            pq.col_Printed = false;
            pq.bFilterPrintRoute = true;
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            Object value = localSettings.Values[Globals.k_str_settings_receipt_print_route];
            try
            {
                pq.col_PrintRoute = Convert.ToByte(value);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            try
            {
                await Globals.client.AddPrintQueueObjectAsync(Globals.token, pq);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            return true;
        }

        public static bool AddOrUpdateValue(string key, object value)
        {
            bool valueChanged = false;
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;

            // If the key exists
            //if (localSettings.Contains(Key))
            if (localSettings.Values.ContainsKey(key))
            {
                // If the value has changed
                if (localSettings.Values[key] != value)
                {
                    // Store the new value
                    localSettings.Values[key] = value;
                    valueChanged = true;
                }
            }
            // Otherwise create the key.
            else
            {
                localSettings.Values.Add(key, value);
                valueChanged = true;
            }

            return valueChanged;
        }
        public static async Task<DateTime> Now()
        {
            DateTime localTime = DateTime.Now;
            try
            {
                DateTime currentUTCTime = await client.GetCurrentTimeAsync(token);
                localTime = TimeZoneInfo.ConvertTime(currentUTCTime, TimeZoneInfo.Local);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            return localTime;
        }
    
    }
    public class CommonUtility
    {
        public static async Task<decimal> CalculateDiscount(decimal decAmount, int iDiscountID, int isplitCount = -1)
        {
            decimal dDiscountDollarAmt = 0;
            if (iDiscountID <= 0)
                return decAmount;

            ServiceReferenceOpenRPOS.Discount discountObject = null;

            if (Globals.DiscountRecords.Where(x => x.col_ID == iDiscountID).Count() == 0)
            {
                ObservableCollection<ServiceReferenceOpenRPOS.Discount> DiscountRecords = await Globals.client.GetDiscountObjectsAsync(Globals.token, "ID=" + iDiscountID.ToString());
                discountObject = DiscountRecords.First();
                Globals.DiscountRecords.Add(discountObject);
            }
            else
                discountObject = Globals.DiscountRecords.Where(x => x.col_ID == iDiscountID).First();


            if (discountObject.col_Amount != 0)
            {
                if (discountObject.col_IsPercent)
                    dDiscountDollarAmt = Math.Round((-1 * (discountObject.col_Amount / 100) * decAmount), 2);
                else
                    if (isplitCount > -1) dDiscountDollarAmt = (-1 * discountObject.col_Amount) / isplitCount;  // get Average Amount if it is Dollar Amount and Applied on Whole Order 
                    else dDiscountDollarAmt = (-1 * discountObject.col_Amount);


                decAmount += dDiscountDollarAmt;
            }

            return decAmount;
        }

    }
}
